//
//  QRCodeScanVC.m
//  Test
//
//  Created by xp on 2017/8/9.
//  Copyright © 2017年 tiantianxiangshang. All rights reserved.
//

#import "HCQRCodeScanVC.h"
#import <AVFoundation/AVFoundation.h>

#define kBgImgX             (DEVW-kBgImgWidth)/2
#define kBgImgY             (NAVBAR_HEIGH+70)*WIDTHSCALE
#define kBgImgWidth         200*WIDTHSCALE
#define kScanLineHeight     2*WIDTHSCALE
#define kBtnWidth           50
#define kBgAlpha            0.6

static NSString *scanBG_img = @"scan_bg";
static NSString *scanLine_img = @"scan_line";
static NSString *torchTurnOn_img = @"torch_on";
static NSString *torchTurnOff_img = @"torch_off";
static NSString *openAlbum_img = @"open_album";
static NSString *ringPath = @"scan_beep";
static NSString *ringType = @"wav";
@interface HCQRCodeScanVC ()<AVCaptureMetadataOutputObjectsDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate>
{
    NSString *QRCode;
}

#pragma mark - ---属性---
/**
 *输入输出中间桥梁(会话)
 */
@property (strong, nonatomic) AVCaptureSession *session;

/**
 *计时器
 */
@property (strong, nonatomic) CADisplayLink *link;

/**
 *实际有效扫描区域的背景图(亦或者自己设置一个边框)
 */
@property (strong, nonatomic) UIImageView *scanbgImg;

/**
 *有效扫描区域循环往返的一条线（这里用的是一个背景图）
 */
@property (strong, nonatomic) UIImageView *scanLine;

/**
 *扫码有效区域外自加的文字提示
 */
@property (strong, nonatomic) UILabel *scanTipLabel;
@property (strong, nonatomic) UILabel *torchTipLabel;
@property (strong, nonatomic) UILabel *albumtipLabel;

/**
 *用于控制照明灯的开启
 */
@property (strong, nonatomic) UIButton *torchBtn;
/**
 *相册
 */
@property (strong, nonatomic) UIButton *albumBtn;

/**
 *用于记录scrollLine的上下循环状态
 */
@property (assign, nonatomic) BOOL up;

#pragma mark -------

@end

@implementation HCQRCodeScanVC

#pragma mark - ---Life Cycle---

- (instancetype)initWithSuccessBlock: (void(^)(NSString *qrCodeInfo))success {
    self = [super init];
    if (self) {
        block = success;
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blackColor];
    //[self setNavigationItem];
    _up = YES;
    
    [self session];
    
    [self.view bringSubviewToFront:self.navView];
    //1.添加一个可见的扫描有效区域的框（这里直接是设置一个背景图片）
    [self.view addSubview:self.scanbgImg];
    
    //2.添加一个上下循环运动的线条（这里直接是添加一个背景图片来运动）
    [self.view addSubview:self.scanLine];
    
    //3.添加其他有效控件
    [self.view addSubview:self.scanTipLabel];
    [self.view addSubview:self.torchBtn];
    [self.view addSubview:self.albumBtn];
     [self.view addSubview:self.albumtipLabel];
     [self.view addSubview:self.torchTipLabel];
    
    self.scanbgImg.sd_layout.topSpaceToView(self.view,kBgImgY).leftSpaceToView(self.view, kBgImgX).widthIs(kBgImgWidth).heightEqualToWidth();
    self.scanLine.sd_layout.topEqualToView(self.scanbgImg).leftEqualToView(self.scanbgImg).rightEqualToView(self.scanbgImg).heightIs(kScanLineHeight);
    self.scanTipLabel.sd_layout.topSpaceToView(self.scanbgImg,20*WIDTHSCALE).leftSpaceToView(self.view,10).rightSpaceToView(self.view,10).heightIs(20);
    
    self.albumBtn.sd_layout.topSpaceToView(self.scanTipLabel,50*WIDTHSCALE).leftEqualToView(self.scanbgImg).offset(10*WIDTHSCALE).widthIs(kBtnWidth).heightEqualToWidth();
    self.torchBtn.sd_layout.topEqualToView(self.albumBtn).rightEqualToView(self.scanbgImg).offset(-10*WIDTHSCALE).widthIs(self.albumBtn.width_sd).heightEqualToWidth();
    
     self.albumtipLabel.sd_layout.topSpaceToView(self.albumBtn,10).centerXEqualToView(self.albumBtn).heightIs(20);
    [self.albumtipLabel setSingleLineAutoResizeWithMaxWidth:DEVW];
    self.torchTipLabel.sd_layout.topEqualToView(self.albumtipLabel).centerXEqualToView(self.torchBtn).heightIs(20);
    [self.torchTipLabel setSingleLineAutoResizeWithMaxWidth:DEVW];

//    [self.scanbgImg updateLayout];
//    self.scanLine.frame=CGRectMake(self.scanbgImg.x, self.scanbgImg.y, self.scanbgImg.width, 2);
    
    
//    self.scrollLine.sd_layout.topSpaceToView(self.bgImg,0).leftSpaceToView(self.bgImg,0).rightSpaceToView(self.bgImg,0).heightIs(2);
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.session startRunning];
    //计时器添加到循环中去
    [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.session stopRunning];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

#pragma mark - ---lazy load---
- (UIImageView *)scanbgImg {
    if (!_scanbgImg) {
        _scanbgImg = [[UIImageView alloc]init];
        _scanbgImg.image = [UIImage imageNamed:scanBG_img];
        _scanbgImg.contentMode=UIViewContentModeScaleAspectFit;
    }
    return _scanbgImg;
}

- (UIImageView *)scanLine {
    if (!_scanLine) {
        _scanLine = [[UIImageView alloc]init];
        _scanLine.image = [UIImage imageNamed:scanLine_img];
        //_scrollLine.contentMode=UIViewContentModeScaleAspectFit;
    }
    return _scanLine;
}
- (UILabel *)scanTipLabel {
    if (!_scanTipLabel) {
        _scanTipLabel = [[UILabel alloc]init];
        _scanTipLabel.text = @"对准二维码即可扫描";
        _scanTipLabel.numberOfLines = 0;
        _scanTipLabel.textColor = [UIColor whiteColor];
        _scanTipLabel.alpha=0.6;
        _scanTipLabel.textAlignment = NSTextAlignmentCenter;
        _scanTipLabel.font = GET_SYSTEM_FONT(TEXT_FONT_28);
    }
    return _scanTipLabel;
}
- (UILabel *)albumtipLabel {
    if (!_albumtipLabel) {
        _albumtipLabel = [[UILabel alloc]init];
        _albumtipLabel.text = @"相册选取二维码";
        //_albumtipLabel.numberOfLines = 0;
        _albumtipLabel.textColor = [UIColor whiteColor];
        _albumtipLabel.textAlignment = NSTextAlignmentCenter;
        _albumtipLabel.font = GET_SYSTEM_FONT(TEXT_FONT_28);
    }
    return _albumtipLabel;
}
- (UILabel *)torchTipLabel {
    if (!_torchTipLabel) {
        _torchTipLabel = [[UILabel alloc]init];
        _torchTipLabel.text = @"打开手电筒";
        //_lampTipLabel.numberOfLines = 0;
        _torchTipLabel.textColor = [UIColor whiteColor];
        _torchTipLabel.textAlignment = NSTextAlignmentCenter;
        _torchTipLabel.font = GET_SYSTEM_FONT(TEXT_FONT_28);
    }
    return _torchTipLabel;
}

- (CADisplayLink *)link {
    if (!_link) {
        _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(scanLineAnimation)];
    }
    return _link;
}

- (UIButton *)torchBtn {
    if (!_torchBtn) {
        _torchBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        //_lamp.alpha = kBgAlpha;
        //_lamp.selected = NO;
//        [_lamp.layer setMasksToBounds:YES];
//        [_lamp.layer setCornerRadius:kLampWidth/2];
//        [_lamp.layer setBorderWidth:2.0];
//        [_lamp.layer setBorderColor:[[UIColor whiteColor] CGColor]];
        //_lamp.backgroundColor = [UIColor whiteColor];
        [_torchBtn setImage:[UIImage imageNamed:torchTurnOff_img] forState:UIControlStateNormal];
        [_torchBtn addTarget:self action:@selector(switchTorch:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _torchBtn;
}
-(UIButton *)albumBtn{
    if (!_albumBtn) {
        _albumBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        //_albumBtn.selected = NO;
        [_albumBtn setImage:[UIImage imageNamed:openAlbum_img] forState:UIControlStateNormal];
        [_albumBtn addTarget:self action:@selector(openAlbum) forControlEvents:UIControlEventTouchUpInside];
    }
    return _albumBtn;
}
- (AVCaptureSession *)session {
    if (!_session) {
        //1.获取输入设备（摄像头）
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        
        //2.根据输入设备创建输入对象
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:NULL];
        if (input == nil) {
            return nil;
        }
        
        //3.创建元数据的输出对象
        AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc]init];
        //4.设置代理监听输出对象输出的数据,在主线程中刷新
        [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        
        // 5.创建会话(桥梁)
        AVCaptureSession *session = [[AVCaptureSession alloc]init];
        //实现高质量的输出和摄像，默认值为AVCaptureSessionPresetHigh，可以不写
        [session setSessionPreset:AVCaptureSessionPresetHigh];
        // 6.添加输入和输出到会话中（判断session是否已满）
        if ([session canAddInput:input]) {
            [session addInput:input];
        }
        if ([session canAddOutput:output]) {
            [session addOutput:output];
        }
        
        // 7.告诉输出对象, 需要输出什么样的数据 (二维码还是条形码等) 要先创建会话才能设置
        output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeCode128Code,AVMetadataObjectTypeCode93Code,AVMetadataObjectTypeCode39Code,AVMetadataObjectTypeCode39Mod43Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeUPCECode,AVMetadataObjectTypePDF417Code,AVMetadataObjectTypeAztecCode];
        
        // 8.创建预览图层
        AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];
        [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
        previewLayer.frame = self.view.bounds;
        [self.view.layer insertSublayer:previewLayer atIndex:0];
        
        //9.设置有效扫描区域，默认整个图层(很特别，1、要除以屏幕宽高比例，2、其中x和y、width和height分别互换位置)
        CGRect rect = CGRectMake(kBgImgY/DEVH, kBgImgX/DEVW, kBgImgWidth/DEVH, kBgImgWidth/DEVW);
        output.rectOfInterest = rect;
        
        //10.设置中空区域，即有效扫描区域(中间扫描区域透明度比周边要低的效果)
        UIView *maskView = [[UIView alloc] initWithFrame:self.view.bounds];
        maskView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:kBgAlpha];
        [self.view addSubview:maskView];
        
        //中间扫描框透明区域
        UIBezierPath *rectPath = [UIBezierPath bezierPathWithRect:self.view.bounds];
        [rectPath appendPath:[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(kBgImgX,kBgImgY, kBgImgWidth, kBgImgWidth) cornerRadius:1] bezierPathByReversingPath]];
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.path = rectPath.CGPath;
        maskView.layer.mask = shapeLayer;
        
        _session = session;
    }
    return _session;
}


#pragma mark - ---NavigationItem---
//- (void)setNavigationItem{
//    self.navigationController.navigationBar.tintColor = [UIColor blackColor];
//    self.navigationItem.title = @"二维码/条形码";
//    UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc]
//                                 initWithTitle:@"相册"
//                                 style:UIBarButtonItemStylePlain
//                                 target:self
//                                 action:@selector(openPhoto)];
//    self.navigationItem.rightBarButtonItem = rightBtn;
//}

- (void)setNavigationTitle:(NSString *)navigationTitle {
    self.navigationItem.title = navigationTitle;
}

- (void)setHideAlbum:(BOOL)hideAlbum {
    self.navigationItem.rightBarButtonItem.customView.hidden = hideAlbum;
}

#pragma mark - 线条运动的动画
- (void)scanLineAnimation {
    if (_up == YES) {
        CGFloat y = self.scanLine.frame.origin.y;
        y += 2;
        self.scanLine.mj_y=y;
        if (y >= (self.scanbgImg.mj_y+self.scanbgImg.width-self.scanLine.height)) {
            _up = NO;
        }
    }else{
        CGFloat y = self.scanLine.frame.origin.y;
        y -= 2;
        self.scanLine.mj_y=y;
        if (y <= self.scanbgImg.mj_y) {
            _up = YES;
        }
    }
}


#pragma mark - 开灯或关灯
- (void)switchTorch:(id)sender {
    UIButton *btn = (UIButton *)sender;
    if (btn.selected == YES) {
        [btn setImage:[UIImage imageNamed:torchTurnOff_img] forState:UIControlStateNormal];
        //btn.backgroundColor = [UIColor whiteColor];
    }else{
        [btn setImage:[UIImage imageNamed:torchTurnOn_img] forState:UIControlStateNormal];
        //btn.backgroundColor = [UIColor clearColor];
    }
    btn.selected = !btn.selected;
    [self openLight:btn.selected];
}


#pragma mark - 调用相册

- (void)openAlbum {
    //1.判断相册是否可以打开
    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
        return;
    }
    //2.创建图片选择控制器
    UIImagePickerController *ipc = [[UIImagePickerController alloc]init];
    ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    ipc.delegate = self;
    //选中之后大图编辑模式
    ipc.allowsEditing = YES;
    [self presentViewController:ipc animated:YES completion:nil];
}

#pragma mark - UIImagePickerControllerDelegate

//相册获取的照片进行处理
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    // 1.取出选中的图片
    UIImage *pickImage = info[UIImagePickerControllerOriginalImage];
    
    CIImage *ciImage = [CIImage imageWithCGImage:pickImage.CGImage];
    
    //2.从选中的图片中读取二维码数据
    //2.1创建一个探测器
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
    
    // 2.2利用探测器探测数据
    NSArray *feature = [detector featuresInImage:ciImage];
    
    // 2.3取出探测到的数据
    for (CIQRCodeFeature *result in feature) {
        NSString *urlStr = result.messageString;
        //二维码信息回传
        if (block) {
            block(urlStr);
        }
        
//        [SystemFunctions showInSafariWithURLMessage:urlStr Success:^(NSString *token) {
//            
//        } Failure:^(NSError *error) {
//            [self showAlertWithTitle:@"该信息无法跳转，详细信息为：" Message:urlStr OptionalAction:@[@"确定"]];
//        }];
    }

    [picker dismissViewControllerAnimated:YES completion:nil];
    
    if (feature.count == 0) {
        [self showAlertWithTitle:@"扫描结果" Message:@"没有扫描到有效二维码" OptionalAction:@[@"确认"]];
    }
}


#pragma mark - AVCaptureMetadataOutputObjectsDelegate
// 扫描到数据时会调用
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    if (metadataObjects.count > 0) {
        [self openShake:YES Sound:YES];
        // 1.停止扫描
                [self.session stopRunning];
        // 2.停止冲击波
                [self.link removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
        
        // 3.取出扫描到得数据
        AVMetadataMachineReadableCodeObject *obj = [metadataObjects lastObject];
        if (obj) {
            //二维码信息回传
            if (block) {
                block([obj stringValue]);
            }
//            
//            [SystemFunctions showInSafariWithURLMessage:[obj stringValue] Success:^(NSString *token) {
//                
//            } Failure:^(NSError *error) {
//                [self.session stopRunning];
//                [self.link removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
//                [self showAlertWithTitle:@"该信息无法跳转，详细信息为：" Message:[obj stringValue] OptionalAction:@[@"确定"]];
//            }];
        }
    }
}

#pragma mark - 提示框
- (void)showAlertWithTitle:(NSString *)title Message:(NSString *)message OptionalAction:(NSArray *)actions {
    
    UIAlertController *alertCtrl = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    [alertCtrl addAction:[UIAlertAction actionWithTitle:actions.firstObject style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        [self.session startRunning];
        [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    }]];
    [self presentViewController:alertCtrl animated:YES completion:nil];
}

#pragma mark - 二维码块传值
- (void)successGetQRCodeInfo:(successBlock)success {
    
    block = success;
}
#pragma mark - 打开设备闪光灯，振动，声音提醒
//是否开启系统闪光灯
-(void)openLight:(BOOL)opened {
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
    if (![device hasTorch]) {
    } else {
        if (opened) {
            // 开启闪光灯
            if(device.torchMode != AVCaptureTorchModeOn ||
               device.flashMode != AVCaptureFlashModeOn){
                [device lockForConfiguration:nil];
                [device setTorchMode:AVCaptureTorchModeOn];
                [device setFlashMode:AVCaptureFlashModeOn];
                [device unlockForConfiguration];
            }
        } else {
            // 关闭闪光灯
            if(device.torchMode != AVCaptureTorchModeOff ||
               device.flashMode != AVCaptureFlashModeOff){
                [device lockForConfiguration:nil];
                [device setTorchMode:AVCaptureTorchModeOff];
                [device setFlashMode:AVCaptureFlashModeOff];
                [device unlockForConfiguration];
            }
        }
    }
}
//是否开启系统震动和声音
-(void)openShake:(BOOL)shaked Sound:(BOOL)sounding {
    if (shaked) {
        //开启系统震动
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    }
    if (sounding) {
        //设置自定义声音
        SystemSoundID soundID;
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:ringPath ofType:ringType]], &soundID);
        AudioServicesPlaySystemSound(soundID);
    }
}

@end
